package avicit.bdp.dgs.mdm.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.dgs.mdm.dao.CodeDAO;
import avicit.bdp.dgs.mdm.dto.CodeDTO;
import avicit.bdp.dgs.mdm.utils.constants.Constants;
import avicit.platform6.api.system.ConvertColumnClient;
import avicit.platform6.api.system.impl.SystemConstant;
import avicit.platform6.commons.utils.BusinessUtil;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.rest.msg.QueryRespBean;
import com.github.pagehelper.Page;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @金航数码科技有限责任公司
 * @作者：developer
 * @邮箱：developer@avic-digital.com
 * @创建时间： 2023-12-06
 * @类说明：CodeService
 * @修改记录：
 * @注意事项：
 * @主要功能：模型中字段编码Service
 */
@Service
public class CodeService extends BaseService<CodeDAO, CodeDTO> {
    private static final Logger logger = LoggerFactory.getLogger(CodeService.class);

    @Autowired
    private CodeDAO codeDAO;

    @Autowired
    private ConvertColumnClient convertColumnClient;

    /**
     * 新增模型
     *
     * @param codeDTO
     * @return
     */
    @Transactional
    public String addCode(CodeDTO codeDTO) {
        checkAddValidity(codeDTO);

        return saveCode2Db(codeDTO);
    }

    /**
     * 删除/批量删除模型，多个id使用英文逗号隔开
     *
     * @param id
     * @return
     */
    @Transactional
    public int deleteCode(String id) {
        if (StringUtils.isBlank(id)) {
            return 0;
        }

        return this.codeDAO.deleteCodeByCond(Arrays.asList(id.trim().split(Constants.COMMA)), null, null);
    }

    /**
     * 修改模型
     *
     * @param codeDTO
     * @return
     */
    @Transactional
    public boolean updateCode(CodeDTO codeDTO) {
        checkUpdateValidity(codeDTO);

        updateCode2Db(codeDTO);

        return true;
    }

    /**
     * 查询模型详情
     *
     * @param id 模型ID
     * @return
     */
    public CodeDTO getCodeDetail(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }

        CodeDTO queryRet = this.mapper.getCodeDetail(id);
        if (queryRet == null) {
            throw new BusinessException("未找到模型，id：" + id);
        }

        valueConvert(Arrays.asList(queryRet));

        return queryRet;
    }

    /**
     * 分页查询模型
     *
     * @param tableId
     * @param keyWords
     * @param code
     * @param pageNo
     * @param pageSize
     * @return
     */
    public QueryRespBean<CodeDTO> queryCode(String tableId, String keyWords, String code, Integer pageNo, Integer pageSize) {
        QueryRespBean<CodeDTO> queryRespBean = new QueryRespBean<>();

        com.github.pagehelper.PageHelper.startPage(pageNo, pageSize);
        Page<CodeDTO> queryRet = this.mapper.queryCodeByCond(tableId);
        queryRespBean.setResult(queryRet);

        valueConvert(queryRet.getResult());

        return queryRespBean;
    }

    /**
     * 编码是否重复
     * 注意：一个字段仅有一个编码规则
     *
     * @param codeId   编码ID，编辑时修改名称，需要传入idd;新增场景不需要传入
     * @param columnId 字段ID
     * @param ruleId   主题ID
     * @return
     */
    public boolean isDuplicateCode(String codeId, String columnId, String ruleId) {
        long count = this.mapper.isDuplicateCode(codeId, columnId, ruleId);
        if (count > 0) {
            return true;
        }

        return false;
    }

    /**
     * 新增模型合法性检查
     *
     * @param codeDTO
     */
    private void checkAddValidity(CodeDTO codeDTO) {
        if (codeDTO == null) {
            throw new BusinessException("入参为null");
        }

        if (StringUtils.isEmpty(codeDTO.getTableId())) {
            throw new BusinessException("模型ID为空");
        }

        if (StringUtils.isEmpty(codeDTO.getColumnId())) {
            throw new BusinessException("字段ID为空");
        }

        if (StringUtils.isEmpty(codeDTO.getRuleId())) {
            throw new BusinessException("编码规则为空");
        }
    }

    /**
     * 新增模型合法性检查
     *
     * @param codeDTO
     */
    private void checkUpdateValidity(CodeDTO codeDTO) {
        if (codeDTO == null) {
            throw new BusinessException("入参为null");
        }

        if (StringUtils.isEmpty(codeDTO.getId())) {
            throw new BusinessException("主键为空");
        }
    }

    /**
     * 持久化到Db
     *
     * @param codeDTO
     * @return
     */
    private String saveCode2Db(CodeDTO codeDTO) {
        if (codeDTO == null) {
            return null;
        }

        codeDTO.setId(ComUtil.getId());
        this.insert(codeDTO);

        BdpLogUtil.log4Insert(codeDTO);

        return codeDTO.getId();
    }

    /**
     * 模型持久化到Db
     *
     * @param codeDTO
     * @return
     */
    private String updateCode2Db(CodeDTO codeDTO) {
        if (codeDTO == null) {
            return null;
        }

        CodeDTO oldDTO = this.codeDAO.selectByPrimaryKey(codeDTO.getId());
        if (oldDTO == null) {
            throw new BusinessException("未找到模型，id：" + codeDTO.getId());
        }

        this.updateByPrimaryKeySelective(codeDTO);

        BdpLogUtil.log4Update(codeDTO, oldDTO);

        return codeDTO.getId();
    }

    /**
     * 通过平台API将字段值转换为名称，包括通用选择组件、通用代码
     *
     * @param dtoList
     */
    private void valueConvert(List<CodeDTO> dtoList) {
        if (CollectionUtils.isEmpty(dtoList)) {
            return;
        }

        // 设置创建者名称
        Map<String, Set<String>> convertFormData = new HashMap<>();
        for (CodeDTO dto : dtoList) {
            BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, dto.getCreatedBy());
        }
        if (convertFormData.size() > 0) {
            //获取请求结果
            Map<String, Map<String, String>> convertResultData = convertColumnClient.replace(convertFormData);
            //循环设置Alias或Name的值
            for (CodeDTO dto : dtoList) {
                dto.setUserName(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER, dto.getCreatedBy()));
            }
        }
    }
}
